import type { RouteLocationAsRelativeGeneric } from 'vue-router'
import type { IMenu } from '../../store/menu'
import { Tree } from '@pkgs/utils'
import { LoadRouteType } from '../../enums'
import useAppStore from '../../store/app'
import useMenuStore from '../../store/menu'
import useMicroStore from '../../store/micro'
import useProjectStore from '../../store/project'
import useTabStore from '../../store/tab'

type IRouterLocation = {
  path: string
  projectCode?: string
  appCode?: string
  menuCode?: string
  menuName?: string
} & Omit<RouteLocationAsRelativeGeneric, 'path'>

export function isFrontendLoadRoute(type: LoadRouteType) {
  return type === LoadRouteType.FRONTEND
}

export function getRouter() {
  const router = useRouter()
  const {
    getProps,
    getIsMicro,
  } = useMicroStore()
  const { getProjectCode } = useProjectStore()
  const { getAppCode } = useAppStore()
  const { addTab } = useTabStore()
  const { getMenus } = useMenuStore()

  function commonHandle(routerLocation: IRouterLocation) {
    const projectCode = routerLocation.projectCode || getProjectCode
    const appCode = routerLocation.appCode || getAppCode

    if (getIsMicro) {
      if (routerLocation.menuCode) {
        getProps.jump({
          projectCode,
          appCode,
          path: routerLocation.path,
          menuCode: routerLocation.menuCode,
          query: routerLocation.query || {},
        })
        return
      }

      if (routerLocation.menuName) {
        getProps.jump({
          menuName: routerLocation.menuName,
          projectCode,
          appCode,
          path: routerLocation.path,
          query: routerLocation.query || {},
        })
        return
      }

      if (!routerLocation.menuCode && !routerLocation.menuName) {
        const menu = new Tree<IMenu>().findNode(getMenus, node => node.path === routerLocation.path)
        if (menu) {
          menu.query = routerLocation.query || {}
          getProps.jump({
            menuName: menu.name,
            projectCode,
            appCode,
            path: routerLocation.path,
            query: routerLocation.query || {},
          })
        }
      }
    }
    else {
      if (routerLocation.menuCode) {
        const menu = new Tree<IMenu>().findNode(getMenus, node => node.code === routerLocation.menuCode)
        if (menu) {
          menu.query = routerLocation.query || {}
          addTab(menu)
        }
        return
      }

      if (routerLocation.menuName) {
        addTab({
          name: routerLocation.menuName,
          code: `${projectCode}_${appCode}_${routerLocation.menuName}`,
          projectCode,
          appCode,
          path: routerLocation.path,
          query: routerLocation.query || {},
        } as any)
        return
      }

      if (!routerLocation.menuCode && !routerLocation.menuName) {
        const menu = new Tree<IMenu>().findNode(getMenus, node => node.path === routerLocation.path)
        if (menu) {
          menu.query = routerLocation.query || {}
          addTab(menu)
        }
      }
    }
  }

  function push(location: IRouterLocation) {
    router.push(location)
    commonHandle(location)
  }

  function replace(location: IRouterLocation) {
    router.replace(location)
    commonHandle(location)
  }

  return {
    push,
    replace,
  }
}
